package com.example.alltestapplication

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.media.AudioAttributes
import android.media.AudioFormat
import android.media.AudioManager
import android.media.AudioRecord
import android.media.AudioTrack
import android.media.MediaRecorder
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.alltestapplication.ui.theme.AllTestApplicationTheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.IOException
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress
import java.net.SocketException
import java.net.SocketTimeoutException
import java.util.concurrent.atomic.AtomicBoolean
import android.media.AudioFocusRequest
import androidx.compose.material3.CardDefaults
import androidx.compose.ui.text.font.FontWeight
import java.net.NetworkInterface
import java.net.Inet4Address
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.material3.RadioButton

class VoiceCallActivity : ComponentActivity() {

    // 日志标记
    companion object {
        private const val TAG = "VoiceCallDebug"
        private const val SAMPLE_RATE = 16000 // 采样率16kHz
        private const val CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO // 单通道
        private const val AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT // 16位PCM
        private const val BUFFER_SIZE = 640 // 每次读取/发送640字节
        
        // 呼叫信令
        private const val SIGNAL_CALL_REQUEST = "CALL_REQUEST"
        private const val SIGNAL_CALL_ACCEPT = "CALL_ACCEPT"
        private const val SIGNAL_CALL_REJECT = "CALL_REJECT"
        private const val SIGNAL_CALL_END = "CALL_END"
        
        // 信令端口
        private const val SIGNAL_PORT = 50000
    }

    // 权限相关
    private val requiredPermissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        arrayOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.INTERNET, 
                Manifest.permission.POST_NOTIFICATIONS)
    } else {
        arrayOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.INTERNET)
    }
    
    private val hasAllPermissions = mutableStateOf(false)
    
    // 协程作用域
    private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
    
    // 网络和音频相关
    private var receiverJob: Job? = null
    private var senderJob: Job? = null
    private var receiveSocket: DatagramSocket? = null
    private var sendSocket: DatagramSocket? = null
    private var audioRecord: AudioRecord? = null
    private var audioTrack: AudioTrack? = null
    private var signalSocket: DatagramSocket? = null
    private var signalListenerJob: Job? = null
    
    // 状态标记
    private val isCallActive = AtomicBoolean(false)
    private val isSenderActive = mutableStateOf(false)
    private val isReceiverActive = mutableStateOf(false)
    
    // 呼叫状态
    private val isIncomingCall = mutableStateOf(false)
    private val callerIp = mutableStateOf("")
    private val callerName = mutableStateOf("")
    private val callerSendPort = mutableStateOf(0)
    private val callerReceivePort = mutableStateOf(0)
    private val callStatus = mutableStateOf("空闲")
    
    // 测试用音量计
    private val receivedVolume = mutableStateOf(0)
    private val sentVolume = mutableStateOf(0)
    
    // 存储设置，方便在UI中显示
    private val uiTargetIp = mutableStateOf("")
    private val uiSendPort = mutableStateOf("50001")
    private val uiReceivePort = mutableStateOf("50002")
    
    // UI状态
    private val localIpAddress = mutableStateOf("获取中...")
    
    // 音频源选项
    data class AudioSourceOption(val name: String, val value: Int)
    
    // 可用音频源列表
    val audioSourceOptions = listOf(
        AudioSourceOption("麦克风 (MIC)", MediaRecorder.AudioSource.MIC),
        AudioSourceOption("语音通信 (VOICE_COMMUNICATION)", MediaRecorder.AudioSource.VOICE_COMMUNICATION),
        AudioSourceOption("语音识别 (VOICE_RECOGNITION)", MediaRecorder.AudioSource.VOICE_RECOGNITION),
        AudioSourceOption("摄像头麦克风 (CAMCORDER)", MediaRecorder.AudioSource.CAMCORDER),
        AudioSourceOption("默认 (DEFAULT)", MediaRecorder.AudioSource.DEFAULT)
    )
    
    // 当前选择的音频源
    val selectedAudioSource = mutableStateOf(MediaRecorder.AudioSource.VOICE_COMMUNICATION)
    
    // 权限请求回调
    private val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        if (permissions.entries.all { it.value }) {
            hasAllPermissions.value = true
            Toast.makeText(this, "所有权限已授予", Toast.LENGTH_SHORT).show()
            startSignalListener()
        } else {
            hasAllPermissions.value = false
            Toast.makeText(this, "需要录音和网络权限才能使用语音通话功能", Toast.LENGTH_LONG).show()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        
        Log.d(TAG, "VoiceCallActivity onCreate")
        
        // 检查权限
        checkPermissions()
        
        // 设置音频流音量为最大
        setMaxVolume()
        
        // 更详细的设备信息记录
        logDeviceAudioInfo()
        
        // 获取本机IP地址
        getLocalIpAddress()
        
        setContent {
            AllTestApplicationTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    VoiceCallScreen(
                        modifier = Modifier.padding(innerPadding),
                        hasPermissions = hasAllPermissions.value,
                        isSenderActive = isSenderActive.value,
                        isReceiverActive = isReceiverActive.value,
                        receivedVolume = receivedVolume.value,
                        sentVolume = sentVolume.value,
                        callStatus = callStatus.value,
                        isIncomingCall = isIncomingCall.value,
                        callerIp = callerIp.value,
                        targetIp = uiTargetIp.value,
                        sendPort = uiSendPort.value,
                        receivePort = uiReceivePort.value,
                        localIpAddress = localIpAddress.value,
                        audioSourceOptions = audioSourceOptions,
                        selectedAudioSource = selectedAudioSource.value,
                        onAudioSourceSelected = { source ->
                            selectedAudioSource.value = source
                        },
                        onTargetIpChange = { uiTargetIp.value = it },
                        onSendPortChange = { uiSendPort.value = it },
                        onReceivePortChange = { uiReceivePort.value = it },
                        onAcceptCall = { acceptIncomingCall() },
                        onRejectCall = { rejectIncomingCall() },
                        onRequestPermissions = { requestPermissions() },
                        onStartCall = { ip, sendPort, receivePort -> startVoiceCall(ip, sendPort, receivePort) },
                        onStopCall = { stopVoiceCall() }
                    )
                }
            }
        }
        
        // 如果已有权限，启动信令监听
        if (hasAllPermissions.value) {
            startSignalListener()
        }
    }
    
    private fun checkPermissions() {
        hasAllPermissions.value = requiredPermissions.all { permission ->
            ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
        }
    }
    
    private fun requestPermissions() {
        requestPermissionLauncher.launch(requiredPermissions)
    }
    
    // 设置音频流音量为最大
    private fun setMaxVolume() {
        try {
            val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
            
            // 使用正常模式，不使用通话模式
            audioManager.mode = AudioManager.MODE_NORMAL
            
            // 获取最大音量
            val musicVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
            
            // 设置媒体音量为最大
//            audioManager.setStreamVolume(
//                AudioManager.STREAM_MUSIC,
//                musicVolume,
//                0
//            )
            
            // 强制使用扬声器
            audioManager.isSpeakerphoneOn = true
            
            Log.d(TAG, "设置音量 - 媒体音量: $musicVolume, 扬声器: 开, 音频模式: MODE_NORMAL")
        } catch (e: Exception) {
            Log.e(TAG, "设置音量失败: ${e.message}")
        }
    }
    
    // 启动信令监听器，用于接收呼叫请求
    private fun startSignalListener() {
        signalListenerJob?.cancel()
        signalListenerJob = coroutineScope.launch(Dispatchers.IO) {
            var localSignalSocket: DatagramSocket? = null
            
            try {
                localSignalSocket = DatagramSocket(SIGNAL_PORT)
                localSignalSocket.soTimeout = 3000 // 3秒超时
                signalSocket = localSignalSocket
                
                Log.d(TAG, "信令监听已启动，端口: $SIGNAL_PORT")
                
                val buffer = ByteArray(1024)
                val packet = DatagramPacket(buffer, buffer.size)
                
                while (isActive) {
                    try {
                        localSignalSocket.receive(packet)
                        
                        // 解析信令
                        val data = String(packet.data, 0, packet.length)
                        val parts = data.split("|")
                        val senderIp = packet.address.hostAddress ?: ""
                        
                        Log.d(TAG, "收到信令: $data, 来自: $senderIp")
                        
                        if (parts.size >= 2) {
                            val signal = parts[0]
                            
                            when (signal) {
                                SIGNAL_CALL_REQUEST -> {
                                    if (parts.size >= 4 && !isCallActive.get() && !isIncomingCall.value) {
                                        val remoteSendPort = parts[1].toIntOrNull() ?: 50001
                                        val remoteReceivePort = parts[2].toIntOrNull() ?: 50002
                                        val callerName = parts[3]
                                        
                                        // 显示来电提示，并自动填充对方信息
                                        withContext(Dispatchers.Main) {
                                            isIncomingCall.value = true
                                            callerIp.value = senderIp
                                            callerSendPort.value = remoteSendPort
                                            callerReceivePort.value = remoteReceivePort
                                            callStatus.value = "来电：$callerName ($senderIp)"
                                            
                                            // 自动填充UI中的值
                                            uiTargetIp.value = senderIp
                                            uiSendPort.value = remoteReceivePort.toString() // 我们的发送端口是对方的接收端口
                                            uiReceivePort.value = remoteSendPort.toString() // 我们的接收端口是对方的发送端口
                                        }
                                    }
                                }
                                SIGNAL_CALL_ACCEPT -> {
                                    if (isCallActive.get() && callStatus.value == "等待对方接听...") {
                                        withContext(Dispatchers.Main) {
                                            callStatus.value = "通话中"
                                            Toast.makeText(this@VoiceCallActivity, "对方已接听", Toast.LENGTH_SHORT).show()
                                        }
                                    }
                                }
                                SIGNAL_CALL_REJECT -> {
                                    if (isCallActive.get() && callStatus.value == "等待对方接听...") {
                                        withContext(Dispatchers.Main) {
                                            stopVoiceCall()
                                            callStatus.value = "对方已拒绝"
                                            Toast.makeText(this@VoiceCallActivity, "对方拒绝了通话", Toast.LENGTH_SHORT).show()
                                        }
                                    }
                                }
                                SIGNAL_CALL_END -> {
                                    withContext(Dispatchers.Main) {
                                        // 强制停止通话，无论当前状态如何
                                        if (isCallActive.get()) {
                                            stopVoiceCall()
                                            callStatus.value = "对方已挂断"
                                            Toast.makeText(this@VoiceCallActivity, "对方已挂断", Toast.LENGTH_SHORT).show()
                                        }
                                    }
                                }
                            }
                        }
                    } catch (e: SocketTimeoutException) {
                        // 超时，继续循环
                        continue
                    } catch (e: Exception) {
                        Log.e(TAG, "信令监听出错: ${e.message}")
                        if (isActive) e.printStackTrace()
                        break
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "信令监听启动失败: ${e.message}")
                e.printStackTrace()
            } finally {
                localSignalSocket?.close()
                Log.d(TAG, "信令监听已停止")
            }
        }
    }
    
    // 发送信令
    private fun sendSignal(targetIp: String, signal: String, additionalData: String = "") {
        coroutineScope.launch(Dispatchers.IO) {
            try {
                val socket = DatagramSocket()
                val data = "$signal|$additionalData".toByteArray()
                val address = InetAddress.getByName(targetIp)
                val packet = DatagramPacket(data, data.size, address, SIGNAL_PORT)
                socket.send(packet)
                socket.close()
                
                Log.d(TAG, "已发送信令: $signal|$additionalData 到 $targetIp:$SIGNAL_PORT")
            } catch (e: Exception) {
                Log.e(TAG, "发送信令失败: ${e.message}")
                e.printStackTrace()
            }
        }
    }
    
    // 开始呼叫
    private fun startVoiceCall(targetIp: String, sendPort: Int, receivePort: Int) {
        if (!hasAllPermissions.value) {
            Toast.makeText(this, "需要权限才能开始通话", Toast.LENGTH_SHORT).show()
            return
        }
        
        if (isCallActive.get()) {
            Toast.makeText(this, "通话已经在进行中", Toast.LENGTH_SHORT).show()
            return
        }
        
        Log.d(TAG, "开始呼叫: $targetIp, 发送端口: $sendPort, 接收端口: $receivePort")
        
        // 测试UDP连接
        testUdpConnection(targetIp, sendPort)
        
        // 发送呼叫请求
        val signalData = "$sendPort|$receivePort|${Build.MODEL}" // 附加设备型号作为呼叫者名称
        sendSignal(targetIp, SIGNAL_CALL_REQUEST, signalData)
        
        // 更新状态
        callStatus.value = "等待对方接听..."
        isCallActive.set(true)
        
        // 启动接收线程
        startReceiver(receivePort)
        
        // 启动发送线程
        startSender(targetIp, sendPort)
        
        Toast.makeText(this, "正在呼叫 $targetIp...", Toast.LENGTH_SHORT).show()
    }
    
    // 测试UDP连接
    private fun testUdpConnection(targetIp: String, port: Int) {
        coroutineScope.launch(Dispatchers.IO) {
            try {
                // 创建测试数据
                val testMessage = "VOICECALL_TEST_PACKET".toByteArray()
                val socket = DatagramSocket()
                val address = InetAddress.getByName(targetIp)
                
                // 发送测试数据
                val packet = DatagramPacket(testMessage, testMessage.size, address, port)
                socket.send(packet)
                
                Log.d(TAG, "UDP连接测试包已发送到 $targetIp:$port")
                
                // 尝试发送多个包，增加连接测试可靠性
                repeat(2) {
                    delay(100)  // 间隔100毫秒
                    socket.send(packet)
                    Log.d(TAG, "额外UDP测试包 #${it+1} 已发送")
                }
                
                socket.close()
            } catch (e: Exception) {
                Log.e(TAG, "UDP连接测试失败: ${e.message}")
                withContext(Dispatchers.Main) {
                    Toast.makeText(
                        this@VoiceCallActivity,
                        "无法连接到目标设备，请检查IP地址和网络连接",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        }
    }
    
    // 接受来电
    private fun acceptIncomingCall() {
        if (!isIncomingCall.value || isCallActive.get()) return
        
        val ip = callerIp.value
        val sendPort = callerReceivePort.value // 对方的接收端口是我们的发送端口
        val receivePort = callerSendPort.value // 对方的发送端口是我们的接收端口
        
        Log.d(TAG, "接受来电: 呼叫方IP: $ip, 我的发送端口: $sendPort, 我的接收端口: $receivePort")
        
        // 发送接受信号
        sendSignal(ip, SIGNAL_CALL_ACCEPT)
        
        // 启动语音通话
        isCallActive.set(true)
        callStatus.value = "通话中"
        
        // 启动接收线程
        startReceiver(receivePort)
        
        // 启动发送线程
        startSender(ip, sendPort)
        
        // 清除来电状态
        isIncomingCall.value = false
        
        Toast.makeText(this, "已接听来自 $ip 的通话", Toast.LENGTH_SHORT).show()
    }
    
    // 拒绝来电
    private fun rejectIncomingCall() {
        if (!isIncomingCall.value) return
        
        // 发送拒绝信号
        sendSignal(callerIp.value, SIGNAL_CALL_REJECT)
        
        // 清除来电状态
        isIncomingCall.value = false
        callStatus.value = "已拒绝来电"
        
        Toast.makeText(this, "已拒绝来自 ${callerIp.value} 的通话", Toast.LENGTH_SHORT).show()
    }
    
    private fun startSender(targetIp: String, sendPort: Int) {
        senderJob = coroutineScope.launch(Dispatchers.IO) {
            var localAudioRecord: AudioRecord? = null
            var localSendSocket: DatagramSocket? = null
            var packetsCount = 0
            var lastLogTime = System.currentTimeMillis()
            
            try {
                // 创建发送Socket
                localSendSocket = DatagramSocket()
                sendSocket = localSendSocket
                
                // 目标地址
                val targetAddress = InetAddress.getByName(targetIp)
                
                Log.d(TAG, "发送器启动: 目标IP: $targetIp, 端口: $sendPort")
                
                // 确保声音被放大处理
                initializeAudio()
                
                // 测试网络连接
                val isReachable = try {
                    targetAddress.isReachable(1000) // 超时1秒
                } catch (e: Exception) {
                    Log.e(TAG, "测试网络连接失败: ${e.message}")
                    false
                }
                Log.d(TAG, "目标设备 $targetIp 是否可达: $isReachable")
                
                // 创建AudioRecord
                val minBufferSize = AudioRecord.getMinBufferSize(
                    SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT
                )
                
                Log.d(TAG, "AudioRecord最小缓冲区大小: $minBufferSize 字节")
                
                if (minBufferSize == AudioRecord.ERROR || minBufferSize == AudioRecord.ERROR_BAD_VALUE) {
                    withContext(Dispatchers.Main) {
                        Toast.makeText(this@VoiceCallActivity, 
                                      "无法初始化AudioRecord", Toast.LENGTH_SHORT).show()
                        isSenderActive.value = false
                    }
                    Log.e(TAG, "AudioRecord初始化失败: 无效的最小缓冲区大小")
                    return@launch
                }
                
                // 使用640的整数倍作为缓冲区大小
                val recordBufferSize = maxOf(minBufferSize, BUFFER_SIZE * 4)
                Log.d(TAG, "使用AudioRecord缓冲区大小: $recordBufferSize 字节")

                if (ActivityCompat.checkSelfPermission(
                        this@VoiceCallActivity,
                        Manifest.permission.RECORD_AUDIO
                    ) != PackageManager.PERMISSION_GRANTED
                ) {
                    Log.e(TAG, "缺少录音权限")
                    return@launch
                }
                
                // 使用选择的音频源创建AudioRecord
                val currentAudioSource = selectedAudioSource.value
                Log.d(TAG, "使用音频源: $currentAudioSource")
                
                localAudioRecord = AudioRecord(
                    currentAudioSource, // 使用用户选择的音频源
                    SAMPLE_RATE,
                    CHANNEL_CONFIG,
                    AUDIO_FORMAT,
                    recordBufferSize
                )
                
                audioRecord = localAudioRecord
                
                // 检查状态
                val recordState = localAudioRecord.state
                if (recordState != AudioRecord.STATE_INITIALIZED) {
                    throw IllegalStateException("AudioRecord初始化失败, 状态: $recordState")
                }
                
                // 开始录音
                localAudioRecord.startRecording()
                Log.d(TAG, "开始录音")
                
                withContext(Dispatchers.Main) {
                    isSenderActive.value = true
                }
                
                // 发送缓冲区
                val buffer = ByteArray(BUFFER_SIZE)
                
                // 发送循环
                while (isActive && isCallActive.get()) {
                    // 读取音频数据
                    val bytesRead = localAudioRecord.read(buffer, 0, BUFFER_SIZE)
                    
                    if (bytesRead > 0) {
                        // 创建数据包并发送
                        val packet = DatagramPacket(buffer, bytesRead, targetAddress, sendPort)
                        localSendSocket.send(packet)
                        packetsCount++
                        
                        // 每秒打印一次状态
                        val now = System.currentTimeMillis()
                        if (now - lastLogTime > 5000) {
                            val rms = calculateRMS(buffer, bytesRead)
                            Log.d(TAG, "发送音频: 已发送 $packetsCount 个音频包, 当前包大小: $bytesRead 字节, 音量RMS: $rms")
                            lastLogTime = now
                            packetsCount = 0
                            
                            // 增加检查机制确认是否有声音
                            if (rms < 0.01) {
                                Log.w(TAG, "警告: 发送的音频音量太低，可能麦克风未正常工作")
                            }
                        }
                        
                        // 计算音量，用于界面显示
                        val volume = calculateVolume(buffer, bytesRead)
                        withContext(Dispatchers.Main) {
                            sentVolume.value = volume
                        }
                    } else if (bytesRead < 0) {
                        Log.e(TAG, "读取音频数据失败: $bytesRead")
                    }
                }
                
            } catch (e: Exception) {
                Log.e(TAG, "发送器错误: ${e.message}")
                withContext(Dispatchers.Main) {
                    Toast.makeText(this@VoiceCallActivity, 
                                  "发送错误: ${e.message}", Toast.LENGTH_SHORT).show()
                    e.printStackTrace()
                }
            } finally {
                // 释放资源
                try {
                    localAudioRecord?.stop()
                    localAudioRecord?.release()
                    Log.d(TAG, "AudioRecord已释放")
                } catch (e: Exception) {
                    Log.e(TAG, "释放AudioRecord失败: ${e.message}")
                    e.printStackTrace()
                }
                
                try {
                    localSendSocket?.close()
                    Log.d(TAG, "发送Socket已关闭")
                } catch (e: Exception) {
                    Log.e(TAG, "关闭发送Socket失败: ${e.message}")
                    e.printStackTrace()
                }
                
                withContext(Dispatchers.Main) {
                    isSenderActive.value = false
                    sentVolume.value = 0
                }
            }
        }
    }
    
    private fun startReceiver(receivePort: Int) {
        receiverJob = coroutineScope.launch(Dispatchers.IO) {
            var localAudioTrack: AudioTrack? = null
            var localReceiveSocket: DatagramSocket? = null
            var packetsCount = 0
            var bytesProcessed = 0
            var lastLogTime = System.currentTimeMillis()
            
            try {
                // 创建接收Socket
                localReceiveSocket = DatagramSocket(receivePort)
                localReceiveSocket.soTimeout = 1000 // 设置1秒超时，方便响应取消
                receiveSocket = localReceiveSocket
                
                Log.d(TAG, "接收器启动: 监听端口 $receivePort")
                
                // 创建AudioTrack
                val minBufferSize = AudioTrack.getMinBufferSize(
                    SAMPLE_RATE, 
                    AudioFormat.CHANNEL_OUT_MONO,
                    AUDIO_FORMAT
                )
                
                Log.d(TAG, "AudioTrack最小缓冲区大小: $minBufferSize 字节")
                
                if (minBufferSize == AudioTrack.ERROR || minBufferSize == AudioTrack.ERROR_BAD_VALUE) {
                    withContext(Dispatchers.Main) {
                        Toast.makeText(this@VoiceCallActivity, 
                                      "无法初始化AudioTrack", Toast.LENGTH_SHORT).show()
                        isReceiverActive.value = false
                    }
                    Log.e(TAG, "AudioTrack初始化失败: 无效的最小缓冲区大小")
                    return@launch
                }
                
                // 使用640的整数倍作为缓冲区大小
                val playbackBufferSize = maxOf(minBufferSize, BUFFER_SIZE * 4)
                Log.d(TAG, "使用AudioTrack缓冲区大小: $playbackBufferSize 字节")

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    localAudioTrack = AudioTrack.Builder()
                        .setAudioAttributes(
                            AudioAttributes.Builder()
                                .setUsage(AudioAttributes.USAGE_MEDIA)  // 使用MEDIA而非VOICE_COMMUNICATION
                                .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                                .build()
                        )
                        .setAudioFormat(
                            AudioFormat.Builder()
                                .setSampleRate(SAMPLE_RATE)
                                .setEncoding(AUDIO_FORMAT)
                                .setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
                                .build()
                        )
                        .setBufferSizeInBytes(playbackBufferSize)
                        .setTransferMode(AudioTrack.MODE_STREAM)
                        .build()
                    
                    // 确保最大音量
                    localAudioTrack.setVolume(1.0f)
                    
                    Log.d(TAG, "创建了高版本AudioTrack, 使用USAGE_MEDIA")
                } else {
                    // 为旧版本Android创建AudioTrack
                    @Suppress("DEPRECATION")
                    localAudioTrack = AudioTrack(
                        AudioManager.STREAM_MUSIC,  // 使用媒体流而非通话流
                        SAMPLE_RATE,
                        AudioFormat.CHANNEL_OUT_MONO,
                        AUDIO_FORMAT,
                        playbackBufferSize,
                        AudioTrack.MODE_STREAM
                    )
                    
                    // 确保最大音量
                    localAudioTrack.setStereoVolume(1.0f, 1.0f)
                    
                    Log.d(TAG, "创建了低版本AudioTrack, 使用STREAM_MUSIC")
                }

                audioTrack = localAudioTrack
                
                // 检查状态
                val trackState = localAudioTrack!!.state
                if (trackState != AudioTrack.STATE_INITIALIZED) {
                    throw IllegalStateException("AudioTrack初始化失败, 状态: $trackState")
                }
                
                // 开始播放
                localAudioTrack.play()
                // 播放测试音
                playTestTone(localAudioTrack)
                Log.d(TAG, "AudioTrack开始播放")
                
                withContext(Dispatchers.Main) {
                    isReceiverActive.value = true
                }
                
                // 接收缓冲区
                val buffer = ByteArray(BUFFER_SIZE)
                val packet = DatagramPacket(buffer, buffer.size)
                
                // 接收循环
                while (isActive && isCallActive.get()) {
                    try {
                        // 接收数据
                        localReceiveSocket.receive(packet)
                        packetsCount++
                        bytesProcessed += packet.length
                        
                        // 每5秒记录一次
                        val now = System.currentTimeMillis()
                        if (now - lastLogTime > 5000) {
                            val lastPacket = if (packet.length > 0) {
                                val rms = calculateRMS(packet.data, packet.length)
                                "，最后音频包RMS: $rms"
                            } else ""
                            
                            Log.d(TAG, "接收音频: 已收到 $packetsCount 个音频包, 共 $bytesProcessed 字节$lastPacket")
                            lastLogTime = now
                            packetsCount = 0
                            bytesProcessed = 0
                        }
                        
                        // 写入AudioTrack播放
                        if (packet.length > 0) {
                            // 确保扬声器模式开启
                            ensureSpeakerphoneOn()
                            
                            // 增加音量增益处理
                            applyVolumeBoost(packet.data, packet.length)
                            
                            // 写入音频数据进行播放
                            val writeResult = localAudioTrack.write(packet.data, 0, packet.length)
                            
                            // 检查音频信号质量
                            val rms = calculateRMS(packet.data, packet.length)
                            if (rms < 0.001) {
                                Log.w(TAG, "警告: 接收到的音频信号非常微弱，可能没有声音数据")
                            } else if (rms > 0.05) {
                                Log.d(TAG, "接收到强音频信号: RMS=$rms")
                            }
                            
                            // 检查写入结果
                            if (writeResult != packet.length) {
                                // 写入错误处理
                                Log.e(TAG, "音频写入错误: 尝试写入 ${packet.length} 字节, 实际写入 $writeResult 字节")
                                withContext(Dispatchers.Main) {
                                    Toast.makeText(
                                        this@VoiceCallActivity,
                                        "音频播放错误: $writeResult",
                                        Toast.LENGTH_SHORT
                                    ).show()
                                }
                            }
                            
                            // 计算音量，用于界面显示
                            val volume = calculateVolume(packet.data, packet.length)
                            withContext(Dispatchers.Main) {
                                receivedVolume.value = volume
                            }
                        }
                    } catch (e: SocketTimeoutException) {
                        // 超时，继续循环
                        continue
                    } catch (e: IOException) {
                        // Socket可能已关闭
                        if (!isActive || !isCallActive.get()) {
                            Log.d(TAG, "Socket已关闭，接收器停止")
                            break
                        }
                        Log.e(TAG, "接收器IO错误: ${e.message}")
                        throw e
                    }
                }
                
            } catch (e: SocketException) {
                // Socket关闭异常，通常是由于停止通话引起的，不需要提示
                if (isActive && isCallActive.get()) {
                    Log.e(TAG, "接收器Socket错误: ${e.message}")
                    withContext(Dispatchers.Main) {
                        Toast.makeText(this@VoiceCallActivity, 
                                      "接收错误: ${e.message}", Toast.LENGTH_SHORT).show()
                        e.printStackTrace()
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "接收器一般错误: ${e.message}")
                withContext(Dispatchers.Main) {
                    Toast.makeText(this@VoiceCallActivity, 
                                  "接收错误: ${e.message}", Toast.LENGTH_SHORT).show()
                    e.printStackTrace()
                }
            } finally {
                // 释放资源
                try {
                    localAudioTrack?.stop()
                    localAudioTrack?.flush()
                    localAudioTrack?.release()
                    Log.d(TAG, "AudioTrack已释放")
                } catch (e: Exception) {
                    Log.e(TAG, "释放AudioTrack失败: ${e.message}")
                    e.printStackTrace()
                }
                
                try {
                    localReceiveSocket?.close()
                    Log.d(TAG, "接收Socket已关闭")
                } catch (e: Exception) {
                    Log.e(TAG, "关闭接收Socket失败: ${e.message}")
                    e.printStackTrace()
                }
                
                withContext(Dispatchers.Main) {
                    isReceiverActive.value = false
                    receivedVolume.value = 0
                }
            }
        }
    }
    
    private fun stopVoiceCall() {
        if (!isCallActive.get()) {
            return
        }
        
        Log.d(TAG, "停止通话")
        
        // 发送挂断信号，确保对方能收到
        if (callerIp.value.isNotEmpty()) {
            // 多发几次挂断信号，增加可靠性
            repeat(3) {
                sendSignal(callerIp.value, SIGNAL_CALL_END)
            }
        }
        
        isCallActive.set(false)
        
        // 关闭Socket会导致receive方法抛出异常，从而退出循环
        receiveSocket?.close()
        sendSocket?.close()
        
        // 取消协程
        receiverJob?.cancel()
        senderJob?.cancel()
        
        // 释放音频资源
        audioRecord?.apply {
            try {
                stop()
                release()
            } catch (e: Exception) {
                Log.e(TAG, "停止AudioRecord错误: ${e.message}")
                e.printStackTrace()
            }
        }
        
        audioTrack?.apply {
            try {
                stop()
                flush()
                release()
            } catch (e: Exception) {
                Log.e(TAG, "停止AudioTrack错误: ${e.message}")
                e.printStackTrace()
            }
        }
        
        audioRecord = null
        audioTrack = null
        receiveSocket = null
        sendSocket = null
        
        // 清除状态
        if (callStatus.value == "等待对方接听..." || callStatus.value == "通话中") {
            callStatus.value = "通话已结束"
        }
        
        Toast.makeText(this, "语音通话已结束", Toast.LENGTH_SHORT).show()
    }
    
    // 计算RMS值，用于调试
    private fun calculateRMS(buffer: ByteArray, length: Int): Double {
        var sum = 0.0
        var count = 0
        
        for (i in 0 until length step 2) {
            if (i + 1 < length) {
                val sample = (buffer[i].toInt() and 0xFF) or ((buffer[i + 1].toInt() and 0xFF) shl 8)
                // 将有符号16位整数转换为-1.0到1.0之间的浮点数
                val normalizedSample = sample / 32768.0
                sum += normalizedSample * normalizedSample
                count++
            }
        }
        
        return if (count > 0) Math.sqrt(sum / count) else 0.0
    }
    
    // 计算音频音量大小，用于界面显示
    private fun calculateVolume(buffer: ByteArray, length: Int): Int {
        var sum = 0L
        for (i in 0 until length step 2) {
            if (i + 1 < length) {
                // 获取16位音频样本值
                val sample = (buffer[i].toInt() and 0xFF) or ((buffer[i + 1].toInt() and 0xFF) shl 8)
                sum += sample * sample
            }
        }
        
        // 音量范围0-10
        val rms = if (length > 0) Math.sqrt(sum.toDouble() / (length / 2)) else 0.0
        return (rms / 3000 * 10).toInt().coerceIn(0, 10)
    }
    
    // 增加音量增益，使音频更清晰
    private fun applyVolumeBoost(buffer: ByteArray, length: Int) {
        val gainFactor = 15.0f  // 大幅增加增益因子到15.0（原来是5.0）
        
        for (i in 0 until length step 2) {
            if (i + 1 < length) {
                // 获取16位音频样本（小端字节序）
                var sample = buffer[i].toInt() and 0xFF
                sample = sample or ((buffer[i + 1].toInt() and 0xFF) shl 8)
                
                // 转换为有符号值（如果最高位为1，则为负数）
                if (sample >= 32768) {
                    sample = sample - 65536
                }
                
                // 应用增益
                var boostedSample = (sample * gainFactor).toInt()
                
                // 限幅
                if (boostedSample > 32767) boostedSample = 32767
                else if (boostedSample < -32768) boostedSample = -32768
                
                // 写回缓冲区（小端字节序）
                buffer[i] = (boostedSample and 0xFF).toByte()
                buffer[i + 1] = ((boostedSample shr 8) and 0xFF).toByte()
            }
        }
    }
    
    // 初始化音频系统
    private fun initializeAudio() {
        try {
            val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
            
            // 先设置模式 - 使用STREAM_MUSIC模式而不是VOICE_CALL
            audioManager.mode = AudioManager.MODE_NORMAL
            
            // 设置音量为最大
//            val musicVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
//
//            audioManager.setStreamVolume(
//                AudioManager.STREAM_MUSIC,
//                musicVolume,
//                0
//            )
            
            // 强制使用扬声器
            audioManager.isSpeakerphoneOn = true
            
            // 请求音频焦点
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val audioAttributes = AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_MEDIA)  // 使用MEDIA而不是VOICE_COMMUNICATION
                    .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                    .build()
                
                val focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
                    .setAudioAttributes(audioAttributes)
                    .setAcceptsDelayedFocusGain(true)
                    .setOnAudioFocusChangeListener { }
                    .build()
                
                val result = audioManager.requestAudioFocus(focusRequest)
                Log.d(TAG, "音频焦点请求结果: $result")
            } else {
                @Suppress("DEPRECATION")
                val result = audioManager.requestAudioFocus(
                    null,
                    AudioManager.STREAM_MUSIC,
                    AudioManager.AUDIOFOCUS_GAIN
                )
                Log.d(TAG, "音频焦点请求结果(旧版): $result")
            }
            
            Log.d(TAG, "音频系统初始化完成: 模式=MODE_NORMAL, 扬声器=开, 音频流=MUSIC")
        } catch (e: Exception) {
            Log.e(TAG, "初始化音频系统失败: ${e.message}")
        }
    }
    
    // 播放测试音以确认AudioTrack工作正常
    private fun playTestTone(audioTrack: AudioTrack) {
        try {
            // 创建一个简单的正弦波测试音
            val duration = 0.2 // 持续0.2秒
            val numSamples = (duration * SAMPLE_RATE).toInt()
            val buffer = ByteArray(numSamples * 2) // 16位采样 = 2字节
            val frequency = 1000.0 // 1000Hz音调
            
            for (i in 0 until numSamples) {
                val time = i.toDouble() / SAMPLE_RATE
                val amplitude = 32767 * 0.5 // 半音量
                val sample = (amplitude * Math.sin(2 * Math.PI * frequency * time)).toInt()
                
                // 16位PCM小端字节序
                buffer[i * 2] = (sample and 0xFF).toByte()
                buffer[i * 2 + 1] = ((sample shr 8) and 0xFF).toByte()
            }
            
            // 播放测试音
            val result = audioTrack.write(buffer, 0, buffer.size)
            Log.d(TAG, "测试音播放结果: $result 字节, 预期: ${buffer.size} 字节")
            
            if (result == AudioTrack.ERROR_INVALID_OPERATION) {
                Log.e(TAG, "测试音播放失败: 无效操作")
            } else if (result == AudioTrack.ERROR_BAD_VALUE) {
                Log.e(TAG, "测试音播放失败: 参数错误")
            } else if (result == AudioTrack.ERROR) {
                Log.e(TAG, "测试音播放失败: 一般错误")
            } else if (result == AudioTrack.ERROR_DEAD_OBJECT) {
                Log.e(TAG, "测试音播放失败: AudioTrack对象已失效")
            }
        } catch (e: Exception) {
            Log.e(TAG, "播放测试音失败: ${e.message}")
            e.printStackTrace()
        }
    }
    
    // 记录设备音频配置信息
    private fun logDeviceAudioInfo() {
        try {
            val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
            
            // 音频硬件信息
            val info = """
                设备音频信息:
                - 设备型号: ${Build.MODEL}
                - Android版本: ${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT})
                - 当前音频模式: ${audioManager.mode}
                - 扬声器开启: ${audioManager.isSpeakerphoneOn}
                - 麦克风静音: ${audioManager.isMicrophoneMute}
                - 本应用采样率: $SAMPLE_RATE Hz
                - 本应用缓冲区大小: $BUFFER_SIZE 字节
                - 通话音量: ${audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL)}/${audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL)}
                - 媒体音量: ${audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)}/${audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)}
            """.trimIndent()
            
            Log.d(TAG, info)
        } catch (e: Exception) {
            Log.e(TAG, "获取设备音频信息失败: ${e.message}")
        }
    }
    
    // 获取本机IP地址
    private fun getLocalIpAddress() {
        coroutineScope.launch(Dispatchers.IO) {
            try {
                val interfaces = NetworkInterface.getNetworkInterfaces()
                while (interfaces.hasMoreElements()) {
                    val networkInterface = interfaces.nextElement()
                    
                    // 跳过非活动接口和回环接口
                    if (!networkInterface.isUp || networkInterface.isLoopback) {
                        continue
                    }
                    
                    // 遍历所有IP地址
                    val addresses = networkInterface.inetAddresses
                    while (addresses.hasMoreElements()) {
                        val address = addresses.nextElement()
                        
                        // 跳过IPv6地址和回环地址
                        if (address is Inet4Address && !address.isLoopbackAddress) {
                            val ip = address.hostAddress
                            withContext(Dispatchers.Main) {
                                localIpAddress.value = ip ?: "未知"
                                Log.d(TAG, "本机IP地址: $ip")
                            }
                            return@launch
                        }
                    }
                }
                
                // 如果没有找到合适的IP地址
                withContext(Dispatchers.Main) {
                    localIpAddress.value = "未找到有效IP"
                }
            } catch (e: Exception) {
                Log.e(TAG, "获取IP地址失败: ${e.message}")
                withContext(Dispatchers.Main) {
                    localIpAddress.value = "获取失败"
                }
            }
        }
    }
    
    // 确保通话时保持扬声器模式
    private fun ensureSpeakerphoneOn() {
        try {
            val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
            if (!audioManager.isSpeakerphoneOn) {
                audioManager.isSpeakerphoneOn = true
                Log.d(TAG, "恢复扬声器模式")
            }
        } catch (e: Exception) {
            Log.e(TAG, "设置扬声器模式失败: ${e.message}")
        }
    }
    
    override fun onPause() {
        super.onPause()
        Log.d(TAG, "Activity onPause, 停止通话")
        stopVoiceCall()
    }
    
    override fun onDestroy() {
        Log.d(TAG, "Activity onDestroy, 清理资源")
        stopVoiceCall()
        signalListenerJob?.cancel()
        signalSocket?.close()
        coroutineScope.cancel()
        super.onDestroy()
    }
}

@Composable
fun VoiceCallScreen(
    modifier: Modifier = Modifier,
    hasPermissions: Boolean,
    isSenderActive: Boolean,
    isReceiverActive: Boolean,
    receivedVolume: Int,
    sentVolume: Int,
    callStatus: String,
    isIncomingCall: Boolean,
    callerIp: String,
    targetIp: String,
    sendPort: String,
    receivePort: String,
    localIpAddress: String,
    audioSourceOptions: List<VoiceCallActivity.AudioSourceOption>,
    selectedAudioSource: Int,
    onAudioSourceSelected: (Int) -> Unit,
    onTargetIpChange: (String) -> Unit,
    onSendPortChange: (String) -> Unit,
    onReceivePortChange: (String) -> Unit,
    onAcceptCall: () -> Unit,
    onRejectCall: () -> Unit,
    onRequestPermissions: () -> Unit,
    onStartCall: (String, Int, Int) -> Unit,
    onStopCall: () -> Unit
) {
    var isCallRunning by remember { mutableStateOf(false) }
    
    // 监听通话状态变化
    LaunchedEffect(callStatus) {
        isCallRunning = callStatus == "等待对方接听..." || callStatus == "通话中"
    }
    
    // 来电提示对话框
    if (isIncomingCall) {
        AlertDialog(
            onDismissRequest = { /* 不允许点击外部关闭 */ },
            title = { Text("来电") },
            text = { Text("收到来自 $callerIp 的语音通话请求，是否接听？") },
            confirmButton = {
                Button(onClick = onAcceptCall) {
                    Text("接听")
                }
            },
            dismissButton = {
                Button(onClick = onRejectCall) {
                    Text("拒绝")
                }
            }
        )
    }
    
    // 使用可滚动布局
    Column(
        modifier = modifier
            .fillMaxSize()
            .verticalScroll(rememberScrollState())
            .padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text(
            text = "局域网语音通话",
            style = MaterialTheme.typography.headlineMedium
        )
        
        // 显示本机IP地址
        Card(
            modifier = Modifier.fillMaxWidth(),
            colors = CardDefaults.cardColors(
                containerColor = MaterialTheme.colorScheme.primaryContainer
            )
        ) {
            Column(
                modifier = Modifier.padding(16.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    text = "本机IP地址",
                    style = MaterialTheme.typography.titleMedium
                )
                Text(
                    text = localIpAddress,
                    style = MaterialTheme.typography.titleLarge,
                    fontWeight = FontWeight.Bold
                )
            }
        }
        
        // 通话状态
        Card(
            modifier = Modifier.fillMaxWidth()
        ) {
            Column(
                modifier = Modifier.padding(16.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    text = "状态: $callStatus",
                    style = MaterialTheme.typography.titleMedium
                )
                
                if (isCallRunning) {
                    Spacer(modifier = Modifier.height(8.dp))
                    Text("发送音量: " + "■".repeat(sentVolume) + "□".repeat(10 - sentVolume))
                    Text("接收音量: " + "■".repeat(receivedVolume) + "□".repeat(10 - receivedVolume))
                }
            }
        }
        
        // 权限提示
        if (!hasPermissions) {
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .clip(RoundedCornerShape(8.dp))
                    .background(Color(0xFFFFEEEE))
                    .padding(16.dp)
            ) {
                Column {
                    Text("需要麦克风和网络权限才能使用语音通话功能")
                    Spacer(modifier = Modifier.height(8.dp))
                    Button(onClick = onRequestPermissions) {
                        Text("请求权限")
                    }
                }
            }
        }
        
        // 音频源选择
        if (!isCallRunning && hasPermissions) {
            AudioSourceSelector(
                audioSourceOptions = audioSourceOptions,
                selectedValue = selectedAudioSource,
                onSourceSelected = onAudioSourceSelected
            )
        }
        
        // 连接信息输入
        OutlinedTextField(
            value = targetIp,
            onValueChange = onTargetIpChange,
            label = { Text("对方IP地址") },
            modifier = Modifier.fillMaxWidth(),
            enabled = !isCallRunning
        )
        
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            OutlinedTextField(
                value = sendPort,
                onValueChange = onSendPortChange,
                label = { Text("发送端口") },
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                modifier = Modifier.weight(1f),
                enabled = !isCallRunning
            )
            
            OutlinedTextField(
                value = receivePort,
                onValueChange = onReceivePortChange,
                label = { Text("接收端口") },
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                modifier = Modifier.weight(1f),
                enabled = !isCallRunning
            )
        }
        
        // 状态显示
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceEvenly,
            verticalAlignment = Alignment.CenterVertically
        ) {
            StatusIndicator(title = "发送状态", isActive = isSenderActive)
            StatusIndicator(title = "接收状态", isActive = isReceiverActive)
        }
        
        Spacer(modifier = Modifier.height(16.dp))
        
        // 通话控制
        Button(
            onClick = {
                if (!isCallRunning) {
                    val parsedSendPort = sendPort.toIntOrNull() ?: 50001
                    val parsedReceivePort = receivePort.toIntOrNull() ?: 50002
                    onStartCall(targetIp, parsedSendPort, parsedReceivePort)
                } else {
                    onStopCall()
                }
            },
            enabled = hasPermissions,
            modifier = Modifier
                .fillMaxWidth()
                .height(56.dp)
        ) {
            Text(if (!isCallRunning) "开始通话" else "结束通话")
        }
        
        // 注意事项
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .clip(RoundedCornerShape(8.dp))
                .background(Color(0xFFE0F7FA))
                .padding(16.dp)
        ) {
            Column {
                Text(
                    text = "使用说明",
                    style = MaterialTheme.typography.titleMedium
                )
                Spacer(modifier = Modifier.height(8.dp))
                Text("1. 确保双方在同一局域网内")
                Text("2. 对方的接收端口应与你的发送端口一致")
                Text("3. 对方的发送端口应与你的接收端口一致")
                Text("4. 通话使用16kHz采样率、单声道PCM")
            }
        }
    }
}

@Composable
fun AudioSourceSelector(
    audioSourceOptions: List<VoiceCallActivity.AudioSourceOption>,
    selectedValue: Int,
    onSourceSelected: (Int) -> Unit
) {
    Card(
        modifier = Modifier.fillMaxWidth(),
        colors = CardDefaults.cardColors(
            containerColor = MaterialTheme.colorScheme.surfaceVariant
        )
    ) {
        Column(
            modifier = Modifier
                .padding(16.dp)
                .selectableGroup()
        ) {
            Text(
                text = "录音通道选择",
                style = MaterialTheme.typography.titleMedium,
                modifier = Modifier.padding(bottom = 8.dp)
            )
            
            audioSourceOptions.forEach { option ->
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(48.dp)
                        .selectable(
                            selected = (option.value == selectedValue),
                            onClick = { onSourceSelected(option.value) }
                        )
                        .padding(horizontal = 16.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    RadioButton(
                        selected = (option.value == selectedValue),
                        onClick = null // null因为我们使用selectable的onClick
                    )
                    Text(
                        text = option.name,
                        style = MaterialTheme.typography.bodyLarge,
                        modifier = Modifier.padding(start = 8.dp)
                    )
                }
            }
        }
    }
}

@Composable
fun StatusIndicator(title: String, isActive: Boolean) {
    Row(verticalAlignment = Alignment.CenterVertically) {
        Text(text = "$title: ")
        Spacer(modifier = Modifier.width(4.dp))
        Box(
            modifier = Modifier
                .size(16.dp)
                .background(
                    color = if (isActive) Color.Green else Color.Red,
                    shape = RoundedCornerShape(8.dp)
                )
        )
    }
} 